//
//  VideoViewController.swift
//  PhotoTestDemo
//
//  Created by 惠 on 2020/9/7.
//  Copyright © 2020 惠. All rights reserved.
//

import UIKit
import Photos
import AVFoundation

class VideoViewController: UIViewController, AVCaptureFileOutputRecordingDelegate {

    private let kScreenW = UIScreen.main.bounds.size.width
    
    //定时器
    var timer: Timer?
    var countTime: Int = 0
    //隐藏提示
    var hiddenAlertTimer: Timer?
    //最短时间
    var minTime: Int = 5
    //设置录制时间
    var videoTime: Int = 45
    
    //选择代理
    var selectedHandler: ((URL)-> Swift.Void)?
    var selectUrl: URL?
    //获取当前方向
    var currentDirection: UIInterfaceOrientation = .portrait
    //颜色
    var colorType: ColorType = .defaults
    //类型
    var selecType: SelectType = .defaults
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        NotificationCenter.default.addObserver(self, selector: #selector(deviceOrientationNotification(noti:)), name: UIDevice.orientationDidChangeNotification, object: nil)
        //开始获取陀螺仪方向
        deviceOrientation.start()
        
        if #available(iOS 10.0, *) {
            if TARGET_IPHONE_SIMULATOR == 1 && TARGET_OS_IPHONE == 1 {
                //模拟器
            } else {
                //真机
                creatUI()
            }
            
        }
        
        setUI()
    }
    
    @objc func deviceOrientationNotification(noti: Notification) {
        let direction = noti.userInfo!["direction"] as? UIInterfaceOrientation
        if direction?.rawValue != nil {
            currentDirection = direction!
        }
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self)
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        captureSession.startRunning()
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        
        captureSession.stopRunning()
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        
        let kScreenH = view.frame.height
        startBtn.frame = CGRect(x: (kScreenW-64)/2, y: kScreenH - 131, width: 64, height: 64)
        timeLabel.frame = CGRect(x: (kScreenW-64)/2, y: kScreenH - 182, width: 64, height: 64)
        finshedBtn.frame = CGRect(x: kScreenW - 56, y: kScreenH - 116, width: 28, height: 28)
        finshedLabel.frame = CGRect(x: kScreenW - 58, y: kScreenH - 84, width: 32, height: 14)
        backButton.frame = CGRect(x: 23, y: kScreenH - 116, width: 28, height: 28)
        remakeLabel.frame = CGRect(x: 23, y: kScreenH - 86, width: 28, height: 28)
        circleView.frame = CGRect(x: (kScreenW-75)/2, y: kScreenH - 137, width: 75, height: 75)
    }
    
    //MARK: -设置UI
    var prepareVideoImage: UIImage!
    var finishedVideoImage: UIImage!
    var stopVideoImage: UIImage!
    func setUI() {
        //初始化开始跟结束按钮
        view.addSubview(circleView)
        circleView.isHidden = true
        view.addSubview(startBtn)
        view.addSubview(timeLabel)
        view.addSubview(finshedBtn)
        view.addSubview(finshedLabel)
        view.addSubview(backButton)
        view.addSubview(remakeLabel)
        
        switch colorType {
        case .defaults:
            prepareVideoImage = UIImage(named: "prepareVideo", in: Resources.getBundle, compatibleWith: nil)
            finishedVideoImage = UIImage(named: "finishedVideo", in: Resources.getBundle, compatibleWith: nil)
            stopVideoImage = UIImage(named: "stopVideo", in: Resources.getBundle, compatibleWith: nil)
            circleView.progressColoar = UIColor(red: 0.25, green: 0.76, blue: 0.8, alpha: 1)
        case .red:
            prepareVideoImage = UIImage(named: "redPrepareVideo", in: Resources.getBundle, compatibleWith: nil)
            finishedVideoImage = UIImage(named: "redFinishedVideo", in: Resources.getBundle, compatibleWith: nil)
            stopVideoImage = UIImage(named: "redStopVideo", in: Resources.getBundle, compatibleWith: nil)
            circleView.progressColoar = UIColor(red: 0.77, green: 0.16, blue: 0.16, alpha: 1)
        }
        startBtn.setImage(prepareVideoImage, for: .normal)
        finshedBtn.setImage(finishedVideoImage, for: .normal)
    }
    
    //MARK: -懒加载UI
    //初始化开始跟结束按钮
    lazy var startBtn: UIButton = {
        let startBtn = UIButton(type: .custom)
        startBtn.backgroundColor = .clear
        startBtn.addTarget(self, action: #selector(startBtnClick(sender:)), for: .touchUpInside)
        return startBtn
    }()
    
    //时间
    lazy var timeLabel: UILabel = {
        let timeLabel = UILabel()
        timeLabel.font = UIFont.systemFont(ofSize: 13)
        timeLabel.textAlignment = .center
        timeLabel.textColor = .white
        timeLabel.backgroundColor = .clear
        timeLabel.text = "0s"
        timeLabel.isHidden = true
        return timeLabel
    }()
    
    //拍好了
    lazy var finshedBtn: UIButton = {
        let finshedBtn = UIButton(type: .custom)
        finshedBtn.backgroundColor = .clear
        finshedBtn.isHidden = true
        finshedBtn.addTarget(self, action: #selector(finshedBtnAction(sender:)), for: .touchUpInside)
        return finshedBtn
    }()
    
    lazy var finshedLabel: UILabel = {
        let finshedLabel = UILabel()
        finshedLabel.backgroundColor = .clear
        finshedLabel.text = "拍好了"
        finshedLabel.font = UIFont.systemFont(ofSize: 10)
        finshedLabel.textColor = .white
        finshedLabel.textAlignment = .center
        finshedLabel.isHidden = true
        return finshedLabel
    }()
    
    //重拍
    lazy var backButton: UIButton = {
        let backButton = UIButton(type: .custom)
        backButton.backgroundColor = .clear
        backButton.setImage(UIImage(named: "returnButton", in: Resources.getBundle, compatibleWith: nil), for: .normal)
        backButton.isHidden = true
        backButton.addTarget(self, action: #selector(returnButtonAction), for: .touchUpInside)
        return backButton
    }()
    
    lazy var remakeLabel: UILabel = {
        let remakeLabel = UILabel()
        remakeLabel.text = "重拍"
        remakeLabel.textColor = .white
        remakeLabel.textAlignment = .center
        remakeLabel.font = UIFont.systemFont(ofSize: 10)
        remakeLabel.isHidden = true
        return remakeLabel
    }()
    
    //圆形进度条
    lazy var circleView = ProgressCirCleView()
    
    //陀螺仪方向
    private let deviceOrientation = DeviceOrientation()
    
    //提示
    private let alertVC = UIAlertController(title: "录制时间过短", message: nil, preferredStyle: .alert)
    
//MARK: -音视频
    /**
     AVCaptureSession 视频捕获 input和output 的桥梁
     videoDevice 视频输入设备
     audioDevice 音频输入设备
     */
    private let captureSession = AVCaptureSession()
    let videoDevice = AVCaptureDevice.default(for: .video)
    private let audioDevice = AVCaptureDevice.default(for: .audio)
    private let fileOutPut = AVCaptureMovieFileOutput()
 
    private var tmpFileUrl:URL?
    
    private var backCamera: AVCaptureDevice?
    private var frontCamera: AVCaptureDevice?
    private var backCameraInput: AVCaptureDeviceInput?
    private var frontCameraInput: AVCaptureDeviceInput?
    private var currentCameraPosition: AVCaptureDevice.Position = .back
    
    //是否开始拍摄
    var isRecording = false
    
    @available(iOS 10.0, *)
    func creatUI() {
        //获取摄像设备
        let session = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaType.video, position: .unspecified)
        let availableCameraDevices = session.devices.compactMap { $0 }
        if !availableCameraDevices.isEmpty {
            for camera in availableCameraDevices {
                if camera.position == .back {
                    backCamera = camera
                } else if camera.position == .front {
                    frontCamera = camera
                }
            }
        }
        //添加视频音频输入设备、添加视频捕获输出
//        let videoInput = try! AVCaptureDeviceInput(device: videoDevice!)
//        captureSession.addInput(videoInput)
        if let backCamera = self.backCamera {
            backCameraInput = try? AVCaptureDeviceInput(device: backCamera)
            if captureSession.canAddInput(backCameraInput!) {
                captureSession.addInput(backCameraInput!)
            }
            self.currentCameraPosition = .back
        } else if let frontCamera = self.frontCamera {
            frontCameraInput = try? AVCaptureDeviceInput(device: frontCamera)
            if captureSession.canAddInput(frontCameraInput!) {
                captureSession.addInput(frontCameraInput!)
            }
            self.currentCameraPosition = .front
        }
        
        let audioInput = try? AVCaptureDeviceInput(device: audioDevice!)
        captureSession.addInput(audioInput!)
        
        captureSession.addOutput(fileOutPut)
        
        let videoLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        videoLayer.frame = view.bounds
        videoLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
        view.layer.addSublayer(videoLayer)

    }
    
    //切换前后摄像头
    func switchCamera(position: AVCaptureDevice.Position)  {
        currentCameraPosition = position
        captureSession.beginConfiguration()
        switch currentCameraPosition {
        case .front:
            switchToBackCamera()
        case .back:
            switchToFrontCamera()
        default :
            break
        }
        captureSession.commitConfiguration()
    }
    
    //显示前置摄像头
    private func switchToFrontCamera() {
        if let backCameraInput = self.backCameraInput, captureSession.inputs.contains(backCameraInput), let frontCamera = self.frontCamera {
            self.frontCameraInput = try? AVCaptureDeviceInput(device: frontCamera)
            captureSession.removeInput(backCameraInput)
            if captureSession.canAddInput(self.frontCameraInput!) {
                captureSession.addInput(self.frontCameraInput!)
                
                self.currentCameraPosition = .front
            }
        }
    }
    
    //显示后置摄像头
    private func switchToBackCamera() {
        if let frontCameraInput = self.frontCameraInput, captureSession.inputs.contains(frontCameraInput), let backCamera = self.backCamera {
            self.backCameraInput = try? AVCaptureDeviceInput(device: backCamera)
            captureSession.removeInput(frontCameraInput)
            if captureSession.canAddInput(self.backCameraInput!) {
                captureSession.addInput(self.backCameraInput!)

                self.currentCameraPosition = .back
            }
        }
    }
    
//MARK: -点击事件
    //开始拍摄
    @objc func startBtnClick(sender:UIButton) -> Void {
        if !isRecording {
            countTime = 0
            timeLabel.text = "\(countTime)s"
            startBtn.setImage(prepareVideoImage, for: .normal)
            //显示进度条
            timeLabel.isHidden = false
            circleView.isHidden = false
            circleView.setProgress(100, animated: true, withDuration: Double(videoTime))
            //设置目录的保存地址
            let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
            let documentDict: String = paths[0]
            let filePath = "\(documentDict)/temp.mp4"
            let fileUrl = URL(fileURLWithPath: filePath)
            tmpFileUrl = fileUrl
            print("xxx fileUrl: \(fileUrl)")
            
            //根据当前设备的方向来设置录像的方向
            let captureConnection = fileOutPut.connection(with: .video)
            if (captureConnection?.isVideoOrientationSupported) != nil {
                captureConnection?.videoOrientation = self.getCaptureVideoOrientation(orientation: currentDirection.rawValue)
            }

            //启动视频编码输出
            fileOutPut.startRecording(to: fileUrl, recordingDelegate: self)

            isRecording = true
            
            timer = Timer.scheduledTimer(timeInterval: 0.99, target: self, selector: #selector(setTime), userInfo: nil, repeats: true)
            
            //隐藏底部视图
            NotificationCenter.default.post(name: NSNotification.Name(rawValue: "bottonSelect"), object: self, userInfo: ["hidden": 1])
        } else {
            if countTime >= minTime {
                //停止获取陀螺仪方向
                deviceOrientation.stop()
                
                showView()
                startBtn.setImage(stopVideoImage, for: .normal)
                fileOutPut.stopRecording()
                circleView.commitAction(time: Float(countTime)/Float(videoTime))
                
                timer?.invalidate()
                timer = nil
            } else {
                startBtn.setImage(prepareVideoImage, for: .normal)
                hiddenView()
                isRecording = false
                
                circleView.commitAction(time: 0)
                switch selecType {
                case .camera:
                    break
                default:
                    //显示底部视图
                    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "bottonSelect"), object: self, userInfo: ["hidden": 0])
                }
                
                timer?.invalidate()
                timer = nil
                
                self.present(alertVC, animated: true, completion: nil)
                hiddenAlertTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(hiddenAlertAction), userInfo: nil, repeats: false)
            }
            
        }
    }
    
    //设置录制视频方向
    func getCaptureVideoOrientation(orientation: Int) -> AVCaptureVideoOrientation {
        var result: AVCaptureVideoOrientation?
  
        switch orientation {
        case 1: break
        case 2:
            result = AVCaptureVideoOrientation.portrait
        case 4:
            result = AVCaptureVideoOrientation.landscapeRight
        case 3:
            result = AVCaptureVideoOrientation.landscapeLeft
        default:
            result = AVCaptureVideoOrientation.portrait
        }
        return result ?? AVCaptureVideoOrientation.portrait
    }
    
    //设置录制视频时间
    @objc func setTime() {
        countTime += 1
        if countTime > videoTime {
            //停止获取陀螺仪方向
            deviceOrientation.stop()
            
            showView()
            startBtn.setImage(stopVideoImage, for: .normal)
            fileOutPut.stopRecording()
            circleView.commitAction(time: Float(countTime)/Float(videoTime))
            
            timer?.invalidate()
            timer = nil
        } else {
            timeLabel.text = "\(countTime)s"
        }
    }
    
    //隐藏提示
    @objc func hiddenAlertAction() {
        alertVC.dismiss(animated: true, completion: nil)
        
        hiddenAlertTimer?.invalidate()
        hiddenAlertTimer = nil
    }
    
    //拍好了
    @objc func finshedBtnAction(sender:UIButton) -> Void {
        self.selectedHandler?(selectUrl!)
    }
    
    //重拍
    @objc func returnButtonAction() {
        //开始获取陀螺仪方向
        deviceOrientation.start()
        
        startBtn.setImage(prepareVideoImage, for: .normal)
        hiddenView()
        isRecording = false
        
        circleView.commitAction(time: 0)
        switch selecType {
        case .camera:
            break
        default:
            //显示底部视图
            NotificationCenter.default.post(name: NSNotification.Name(rawValue: "bottonSelect"), object: self, userInfo: ["hidden": 0])
        }
    }
    
    //显示视图
    func showView() {
        finshedBtn.isHidden = false
        finshedLabel.isHidden = false
        backButton.isHidden = false
        remakeLabel.isHidden = false
        
    }
    
    //隐藏视图
    func hiddenView() {
        finshedBtn.isHidden = true
        finshedLabel.isHidden = true
        backButton.isHidden = true
        remakeLabel.isHidden = true
        timeLabel.isHidden = true
        circleView.isHidden = true
    }

//MARK: -视频处理AVCaptureFileOutputRecordingDelegate
    func fileOutput(_ output: AVCaptureFileOutput, didStartRecordingTo fileURL: URL, from connections: [AVCaptureConnection]) {
        print("StartRecording 开始")
    }
    
    func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
        if isRecording {
            //将录制好的录像保存到照片库中
//            PHPhotoLibrary.shared().performChanges({
//                
//                PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: outputFileURL)
//            }) { (isSuccess:Bool, error:Error?) in
//                
//            }
            self.selectUrl = outputFileURL
            print(outputFileURL)
        }
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    
}
